#!/usr/bin/env bash
set -e # 这告诉bash一但有任何一个语句返回非真的值，则退出bash。

PROG_NAME=`basename $0`
PROG_DIR=`dirname $0`
PROG_DIR=`cd "$PROG_DIR" && pwd`

. "$PROG_DIR/vic/log.sh"

function print_help {
    echo -e "Usage: $PROG_NAME [options] [path]"
    echo -e ""
    echo -e "Options:"
    echo -e "  -c, --cpp"
    echo -e "    Find c, c++ file."
    echo -e ""
    echo -e "  -e PATH, --exclude=PATH"
    echo -e "    Exclude path."
    echo -e ""
    echo -e "  -h, --head"
    echo -e "    Find *.h file."
    echo -e ""
    echo -e "  -j, --jce"
    echo -e "    Find *.jce file."
    echo -e ""
    echo -e "  -k KEYWORD, --key=KEYWORD"
    echo -e "    Grep keyword."
    echo -e ""
    echo -e "  -n NAME, --name=NAME"
    echo -e "    Find file name."
    echo -e ""
    echo -e "  -p, --proto"
    echo -e "    Find *.proto file."
    echo -e ""
    echo -e "  -t TYPE, --type=TYPE"
    echo -e "    Find file type. eg:"
    echo -e "    b  block (buffered) special."
    echo -e "    c  character (unbuffered) special."
    echo -e "    d  directory."
    echo -e "    p  named pipe (FIFO)."
    echo -e "    r  regular file."
    echo -e "    l  symbolic link."
    echo -e "    s  socket."
    echo -e ""
    echo -e "  --help"
    echo -e "    Displays help message"
    echo -e ""
}

CMD_GETOPT=`getopt -o ce:hjk:n:pt: --long cpp,exclude:,head,jce,key:,name:,proto,type:,help -n 'example.bash' -- "$@"`
CMD_GETOPT_RET=$?
if [ $CMD_GETOPT_RET -ne 0 ] ; then
    exit $CMD_GETOPT_RET
fi
eval set -- "$CMD_GETOPT"

function append_exclude_path {
    for ARG in "$@"
    do
        if [[ -n $EXCLUDE_PATH ]] ; then
            EXCLUDE_PATH="$EXCLUDE_PATH -o -path \"$ARG\""
        else
            EXCLUDE_PATH="-path \"$ARG\""
        fi
    done
}

function append_file_name {
    for ARG in "$@"
    do
        if [[ -n $FIND_NAME ]] ; then
            FIND_NAME="$FIND_NAME -o -name \"$ARG\""
        else
            FIND_NAME="-name \"$ARG\""
        fi
    done
}

function append_file_type {
    for ARG in "$@"
    do
        if [[ -n $FIND_TYPE ]] ; then
            FIND_TYPE="$FIND_TYPE -o -type \"$ARG\""
        else
            FIND_TYPE="-type \"$ARG\""
        fi
    done
}

#append_exclude_path "*/NetCommand" "*/DbData" "*/.svn" "*/.git"
append_exclude_path "*/.svn" "*/.git"

while true ; do
    case "$1" in
        -c|--cpp) append_file_name "*.c" "*.cpp" ; shift ;;
        -e|--exclude) append_exclude_path "$2" ; shift 2 ;;
        -h|--head) append_file_name "*.h" "*.hpp" ; shift ;;
        -j|--jce) append_file_name "*.jce" ; shift ;;
        -k|--key) GREP_KEY="$2" ; shift 2 ;;
        -n|--name) append_file_name "$2" ; shift 2 ;;
        -p|--proto) append_file_name "*.proto" ; shift ;;
        -t|--type) append_file_type "$2" ; shift 2 ;;
        --help) print_help; exit 1 ;;
        --) shift; break ;;
        *) echo "Unknown option: $1"; print_help; exit 1 ;;
    esac
done

#if [[ "$GREP_KEY" = "" ]] ; then
if [[ -z $GREP_KEY ]] ; then
    echo "Grep keyword is empty."
    exit 1
fi

for arg do
    FIND_PATH="$FIND_PATH $arg"
done

append_file_type f l

vic_log_debug "EXCLUDE_PATH: $EXCLUDE_PATH"
vic_log_debug "FIND_NAME: $FIND_NAME"
vic_log_debug "FIND_TYPE: $FIND_TYPE"
vic_log_debug "FIND_PATH: $FIND_PATH"

if [[ -n $EXCLUDE_PATH ]] ; then
    FIND_ARGS="\( \( $EXCLUDE_PATH \) -prune -o -path \"*\" \)"
fi
if [[ -n $FIND_NAME ]] ; then
    if [[ -n $FIND_ARGS ]] ; then
        FIND_ARGS="$FIND_ARGS -a \( $FIND_NAME \)"
    else
        FIND_ARGS="\( $FIND_NAME \)"
    fi
fi
if [[ -n $FIND_TYPE ]] ; then
    if [[ -n $FIND_ARGS ]] ; then
        FIND_ARGS="$FIND_ARGS -a \( $FIND_TYPE \)"
    else
        FIND_ARGS="\( $FIND_TYPE \)"
    fi
fi
if [[ -n $FIND_PATH ]] ; then
    if [[ -n $FIND_ARGS ]] ; then
        FIND_ARGS="$FIND_PATH $FIND_ARGS"
    else
        FIND_ARGS="$FIND_PATH"
    fi
fi
FIND_EXP="find $FIND_ARGS"
vic_log_debug "FIND_EXP: $FIND_EXP"
eval $FIND_EXP | xargs grep --color=auto -n "$GREP_KEY"

